package com.tiny.controller;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;

import com.jfinal.core.Controller;
import com.jfinal.log.Logger;
import com.tiny.model.User;
import com.tiny.shiro.CaptchaRender;
import com.tiny.shiro.CaptchaUsernamePasswordToken;
import com.tiny.shiro.IncorrectCaptchaException;

public class LoginController extends Controller {
    
    private static final Logger LOG = Logger.getLogger(LoginController.class);
    private static final int DEFAULT_CAPTCHA_LEN = 4;
    private static final String LOGIN_URL = "/login";
    
    public void index(){
    	if(!SecurityUtils.getSubject().isAuthenticated()){
    		this.createToken("loginToken");
    		this.render("/login.html");
    	}
    	else{
    		this.render("/index.html");
    	}
    }
    
    public void login(){
    	this.createToken("loginToken");
    	this.render("/login.html");
    }
    
    public void renderIndex(){
        this.render("/index.html");
    }
    
    /**
     * @Title: img  
     * @Description: 图形验证码   
     * @since V1.0.0
     */
    public void img(){
        CaptchaRender img = new CaptchaRender(DEFAULT_CAPTCHA_LEN);
        this.setSessionAttr(CaptchaRender.DEFAULT_CAPTCHA_MD5_CODE_KEY, img.getMd5RandonCode());
        render(img);
    }
    
    public void indexDoLogin(){
        try {
            CaptchaUsernamePasswordToken token = new CaptchaUsernamePasswordToken(this.getPara("username"),this.getPara("password"),false,"", this.getPara("captcha"));
            Subject subject = SecurityUtils.getSubject();
            ThreadContext.bind(subject);
            //进行用用户名和密码验证
            subject.login(token);
            //获取当前用户，并将当前用户保存在Session中。
            User user = User.dao.findByUsername(token.getUsername());
            this.setSessionAttr("user", user);
            this.renderJson("{\"success\":\"true\"}");
        } catch (IncorrectCaptchaException e) {
        	LOG.error(e.getMessage());
        	e.printStackTrace();
            this.redirect(LOGIN_URL);
        } catch (LockedAccountException e) {
        	LOG.error(e.getMessage());
        	e.printStackTrace();
            this.redirect(LOGIN_URL);
        } catch (AuthenticationException e) {
        	LOG.error(e.getMessage());
        	e.printStackTrace();
            this.redirect(LOGIN_URL);
        } catch (Exception e) {
            LOG.error(e.getMessage());
            e.printStackTrace();
            this.redirect(LOGIN_URL);
        }
    }
    
    
    public void doLogin(){
        try {
            CaptchaUsernamePasswordToken token = new CaptchaUsernamePasswordToken(this.getPara("username"),this.getPara("password"),false,"", this.getPara("captcha"));
            Subject subject = SecurityUtils.getSubject();
            ThreadContext.bind(subject);
            //进行用用户名和密码验证
            subject.login(token);
            //获取当前用户，并将当前用户保存在Session中。
            User user = User.dao.findByUsername(token.getUsername());
            //this.setSessionAttr("user", user);
            //调转到主页面
            this.redirect("/renderIndex");
            //this.renderJson("{\"success\":\"true\"}");
        } catch (IncorrectCaptchaException e) {
        	LOG.error(e.getMessage());
        	e.printStackTrace();
            this.redirect(LOGIN_URL);
        } catch (LockedAccountException e) {
        	LOG.error(e.getMessage());
        	e.printStackTrace();
            this.redirect(LOGIN_URL);
        } catch (AuthenticationException e) {
        	LOG.error(e.getMessage());
        	e.printStackTrace();
            this.redirect(LOGIN_URL);
        } catch (Exception e) {
            LOG.error(e.getMessage());
            e.printStackTrace();
            this.redirect(LOGIN_URL);
        }
    }
    
    @RequiresAuthentication
    public void logout() {
        Subject currentUser = SecurityUtils.getSubject();
        try {
            currentUser.logout();
            //this.removeSessionAttr("user");
            this.redirect(LOGIN_URL);
        } catch (SessionException ise) {
            LOG.debug("Encountered session exception during logout.  This can generally safely be ignored.", ise);
        } catch (Exception e) {
            LOG.debug("登出发生错误", e);
        }
    }
}
